package com.xframe.domain.sys;


import com.xframe.domain.BaseModel;
import com.xframe.domain.role.IUserCredentials;
import com.xframe.xdal.core.DataBaseAccess;
import com.xframe.xdal.core.annotation.*;
import com.xframe.xdal.core.constant.*;
import com.xframe.xdal.core.exception.DalFrameException;
import com.xframe.xdal.core.tran.DbTransactionContext;
import com.xframe.xdal.core.tran.IDbTransaction;
import com.xframe.xdal.core.tran.XTransaction;
import com.xframe.xdal.core.util.XDateUtil;
import lombok.Data;
import lombok.extern.log4j.Log4j2;

import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 数据源
 *
 * @author xufeng
 * @version 1.0
 * @date 2023-03-28
 */
@Log4j2
@Data
@XTable(value = "SYS_DATASOURCE", label = "数据源")
@XSelectItem(keyName = "sourceId",codeName = "code",textName = "name")
public class SysDataSource extends BaseModel {
    /**
     * 数据源ID
     */
    @AutoFill(AutoFillType.Snowflake)
    @XColumn(name = "SOURCE_ID", primaryKeyFlag = true,desc = "数据源ID")
    private Long sourceId;

    /**
     * 数据源编码
     */
    @XQueryCondition
    @XGridTableRef
    @XColumn(name = "DS_CODE",uniqueFlag = true,desc = "数据源编码",length = 20)
    private String code;

    /**
     * 数据源名称
     */
    @XColumn(name = "DS_NAME",desc = "数据源名称",length = 20)
    private String name;

    /**
     * 数据源描述
     */
    @XColumn(name = "DS_DESC",desc = "数据源描述",length = 50,nullFlag = true)
    private String desc;

    /**
     * 数据库类型
     */
    @XColumn(name = "DS_TYPE",desc = "数据库类型",length = 20)
    private String type;

    /**
     * 主机IP
     */
    @XColumn(name = "DS_HOST",desc = "主机IP",length = 50)
    private String host;

    /**
     * 端口
     */
    @XColumn(name = "DS_PORT",desc = "端口")
    private Integer port;

    /**
     * 用户名
     */
    @XColumn(name = "DS_USER",desc = "用户名",length = 50)
    private String userName;

    /**
     * 密码
     */
    @AutoFill(value = AutoFillType.ENCRYPT,overwrite= true,operateMark = OperateMark.Create | OperateMark.Update)
    @AutoFill(value = AutoFillType.DECRYPT,overwrite= true,operateMark = OperateMark.Read)
    @XColumn(name = "DS_PWD",desc = "密码",length = 1000)
    private String pwd;

    /**
     * 数据库名称
     */
    @XColumn(name = "DS_DB_NAME",desc = "数据库名称",length = 50)
    private String dbName;

    /**
     * 数据库名称
     */
    @XColumn(name = "DS_SCHEMA_NAME",desc = "数据库架构",length = 50)
    private String schema;

    /**
     * 测试连接数据源
     */
    @XTransaction
    @XAction(code = "testConnect",desc = "连接测试数据源")
    public Object testDataSourecConnect(){
        log.info("call testDataSourecConnect");
        try {
            DataSourceTypeEnums dataType = DataSourceTypeEnums.valueOf(this.type);
            DataBaseAccess.registerDataSource(dataType, this.code, this.host, this.port, this.userName, this.pwd, this.dbName);
            Object value = DataBaseAccess.getInstanceByName(this.code).testConnect();
            if (Date.class.isAssignableFrom(value.getClass())) {
                return XDateUtil.parseDateToStr(XDateUtil.YYYY_MM_DD_HH_MM_SS,(Date) value);
            }
            return value;
        }catch (java.lang.IllegalArgumentException exception){
            throw new DalFrameException(ErrorCode.DATABASE_TYPE_ERROR, ErrorMsg.DATABASE_TYPE_ERROR_MSG);
        }catch (Exception exception){
            throw new DalFrameException(ErrorCode.DATABASE_CONNECT_ERROR, ErrorMsg.DATABASE_CONNECT_ERROR_MSG);
        }
    }

    /**
     * 测试连接数据源
     * {'boolVal':false,'boolVal2':true,'dateVal':1691975420040,'doubleVal':3.1415927,'intVal':1,'integerVal':100,
     * 'map':{'x1':'VAL1','x2':'VAL2'},'strVal':'strVal===>{}','strlist':['C++','JAVA','OpenGL'],'testEnumPar':'Open',
     * 'testModelObjPar':{'code':'ok','name':'test001'}}
     */
    @XExecTime
    @XTransaction
    @XAction(desc = "连接测试数据源")
    public Object testDataSourecConnect1(@XActionParameter(name = "strVal") String strVal,
                                         @XActionParameter(name = "intVal") int intVal,
                                         @XActionParameter(name = "integerVal") Integer integerVal,
                                         @XActionParameter(name = "boolVal") Integer boolVal,
                                         @XActionParameter(name = "boolVal2") Integer boolVal2,
                                         @XActionParameter(name = "dateVal") Date dateVal,
                                         @XActionParameter(name = "doubleVal") Double doubleVal,
                                         //@XActionParameter(name = "testEnumPar") TestPar testEnumPar,
                                         @XActionParameter(name = "strlist") List<String> strlist,
                                         @XActionParameter(name = "map") Map<String,Object> map,
                                         //@XActionParameter(name = "testModelObjPar") TestModelObjPar testModelObjPar,
                                         IUserCredentials userCredentials){

        log.info("strVal = {}",strVal);
        log.info("intVal = {}",intVal);
        log.info("integerVal = {}",integerVal);
        log.info("boolVal = {}",boolVal);
        log.info("boolVal2 = {}",boolVal2);
        log.info("dateVal = {}",dateVal);
        log.info("doubleVal = {}",doubleVal);
        //log.info("testEnumPar = {}",testEnumPar);
        log.info("strlist = {}",strlist);
        log.info("map = {}",map);
        //log.info("testModelObjPar = {}",testModelObjPar);
        log.info("userCredentials = {}",userCredentials);

        IDbTransaction transaction = DbTransactionContext.getTrans();
        if(transaction != null){
            log.info("transaction != null");
        }

        return "OK";
    }

    @XAction(code = "staticTest",desc = "连接测试数据源")
    public static Object staticTest(){
        return new Date();
    }


}
